/*
 * <h3>Title:wheel-spring-boot-web-starter系统</h3>
 * <p>Copyright (c) 2019, wnfbx@163.com. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package com.wheel.autoconfigure.web.mvc;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.wheel.autoconfigure.web.mvc.returnvaluehandler.ResultModelAttributeMethodProcessor;
import com.wheel.core.utils.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import java.text.SimpleDateFormat;


/**
 * <dt>Description:WebMvcAutoConfigurerAdapter</dt>
 * <dd>mvc 自动配置</dd>
 *
 * @author wnfbx@163.com
 * @version 1.0 <i>2019年6月6日 下午1:14:05</i>
 * @since jdk1.7+
 */
public class WebMvcAutoConfigurerAdapter implements WebMvcConfigurer {

    private static final Logger log = LoggerFactory.getLogger(WebMvcAutoConfigurerAdapter.class);

    /**
     * <dt>Description:WebMvcAutoConfigurerAdapter</dt>
     * <dd>初始化异常消息code message映射配置</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version 1.0 <i>2019年6月6日 下午1:06:56</i></dd>
     *
     * @since jdk1.7+
     */
    public WebMvcAutoConfigurerAdapter() {
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {

    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        //springboot2需要先开启开启配置spring.mvc.pathmatch.use-suffix-pattern=true
        //参考下面配置
//        spring.mvc.contentnegotiation.favor-parameter=false # Whether a request parameter ("format" by default) should be used to determine the requested media type.
//        spring.mvc.contentnegotiation.favor-path-extension=false # Whether the path extension in the URL path should be used to determine the requested media type.
//        spring.mvc.contentnegotiation.media-types.*= # Map file extensions to media types for content negotiation. For instance, yml to text/yaml.
//        spring.mvc.contentnegotiation.parameter-name= # Query parameter name to use when "favor-parameter" is enabled.


//        if (webMvcAutoConfigurationProperties.isEnableContentNegotiation()) {
//            configurer
//                    //根据后缀名选择视图，参考配置spring.mvc.contentnegotiation.favor-path-extension
////                .favorPathExtension(true)
//                    //忽略header里的Accept
//                    .ignoreAcceptHeader(true)
//                    // 请求中扩展名以.json 按JSON处理
//                    .mediaType("json", MediaType.APPLICATION_JSON)
//                    // 请求中扩展名以.xml 按xml处理
//                    .mediaType("xml", MediaType.TEXT_XML)
//                    // 请求中扩展名以.html 按html处理
//                    .mediaType("html", MediaType.TEXT_HTML)
//                    // 设置默认的mediatype,在没有扩展名和参数时的默认展现形式
////                .defaultContentType(MediaType.APPLICATION_JSON);
//                    .defaultContentType(MediaType.TEXT_PLAIN);
//        }
    }

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {

    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

    }

    @Override
    public void addFormatters(FormatterRegistry registry) {

    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        Log.configured(log, "Interceptors");

        regI18NInterceptor(registry);

    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // registry.addMapping("/**") // **代表所有路径
        // .allowedOrigins("*") //
        // allowOrigin指可以通过的ip，*代表所有，可以使用指定的ip，多个的话可以用逗号分隔，默认为*
        // .allowedMethods("GET", "POST", "HEAD", "PUT", "DELETE") // 指请求方式
        // 默认为*
        // .allowCredentials(false) // 支持证书，默认为true
        // .maxAge(3600) // 最大过期时间，默认为-1
        // .allowedHeaders("*");
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
//
        ObjectMapper objectMapper = new ObjectMapper();
        // 设置时间转换格式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 设置空对象可以继续转换
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 设置不关心属性是否与目标对象一致
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MappingJackson2JsonView mappingJackson2JsonView = new MappingJackson2JsonView(objectMapper);

        registry.enableContentNegotiation(mappingJackson2JsonView);

    }

    @Override
    public void addArgumentResolvers(java.util.List<HandlerMethodArgumentResolver> argumentResolvers) {

    }

    @Override
    public void addReturnValueHandlers(java.util.List<HandlerMethodReturnValueHandler> returnValueHandlers) {
        returnValueHandlers.add(new ResultModelAttributeMethodProcessor());//responsebody handler 在自定义handler之前，此处添加无用，需插入到原生responsebody handler前
    }

    @Override
    public void configureMessageConverters(java.util.List<HttpMessageConverter<?>> converters) {

    }

    @Override
    public void extendMessageConverters(java.util.List<HttpMessageConverter<?>> converters) {
        Log.debug(log, "converter size:{}", converters.size());
    }

    @Override
    public void configureHandlerExceptionResolvers(java.util.List<HandlerExceptionResolver> exceptionResolvers) {

    }

    @Override
    public void extendHandlerExceptionResolvers(java.util.List<HandlerExceptionResolver> exceptionResolvers) {

    }

    @Override
    public Validator getValidator() {
        return null;
    }

    @Override
    public MessageCodesResolver getMessageCodesResolver() {
        return null;
    }

    /**
     * <dt>Description:regI18NInterceptor</dt>
     * <dd>设置国际化拦截器，处理请求中的国际化消息<br/>
     * 例 helloworld?locale=en<br/>
     * 可以查看动态更换locale后的效果。如不想每次都加参数locale，需CookieLocaleResolver支持
     * </dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2019/12/24 14:49</i></dd>
     *
     * @param registry 注册器
     * @see org.springframework.web.servlet.i18n.CookieLocaleResolver
     * @since jdk1.7+
     */
    private void regI18NInterceptor(InterceptorRegistry registry) {
        registry.addInterceptor(new org.springframework.web.servlet.i18n.LocaleChangeInterceptor());
    }
}
